package com.wyz.saas.common.view.airpanel

import android.app.Activity
import android.graphics.Point
import android.graphics.Rect
import android.util.Log
import android.view.View
import com.wyz.saas.common.R
import java.util.concurrent.atomic.AtomicBoolean


class AirPanelHelper : AirPanel.Helper {

    private var mView: View
    private var mAttribute: AirAttribute

    private var mTarget: AirPanel.Helper? = null
    private var mPanelListenerTmp: AirPanel.PanelListener? = null
    private var mOnStateChangedListenerTmp: AirPanel.OnStateChangedListener? = null

    constructor(
        view: View,
        attribute: AirAttribute
    ) {
        mView = view
        mAttribute = attribute
    }

    override fun setup(activity: Activity) {
        mTarget = if (mView.id == R.id.tag_airPanelSubLayout) {
            AirPanelView(mView, mAttribute)
        } else {
            val childPanel = mView.findViewById<View>(R.id.tag_airPanelSubLayout)
                ?: throw RuntimeException("AirPanel child can't null. You must set child id:airPanelLayout")
            AirPanelLayout(childPanel as AirPanel.Panel)
        }
        mPanelListenerTmp?.let { mTarget?.setup(it) }
        mOnStateChangedListenerTmp?.let { mTarget?.setOnStateChangedListener(it) }

        mTarget?.setup(activity)

        mPanelListenerTmp = null
        mOnStateChangedListenerTmp = null
    }

    override fun setup(panelListener: AirPanel.PanelListener) {
        mTarget?.setup(panelListener) ?: let {
            mPanelListenerTmp = panelListener
        }
    }


    override fun isOpen(): Boolean {
        return mTarget != null && mTarget!!.isOpen()
    }

    override fun closePanel() {
        mTarget?.closePanel()
    }

    override fun openPanel() {
        mTarget?.openPanel()
    }

    /**
     * 计算并返回测量高度
     */
    override fun calculateHeightMeasureSpec(heightMeasureSpec: Int): Int {
        return mTarget?.calculateHeightMeasureSpec(heightMeasureSpec) ?: let { heightMeasureSpec }
    }

    /**
     * 设置高度
     */
    override fun adjustPanelHeight(heightMeasureSpec: Int) {
        mTarget?.adjustPanelHeight(heightMeasureSpec)
    }

    /**
     * 设置状态监听
     */
    override fun setOnStateChangedListener(listener: AirPanel.OnStateChangedListener) {
        mTarget?.setOnStateChangedListener(listener) ?: let {
            mOnStateChangedListenerTmp = listener
        }
    }

    /**
     * 请求隐藏输入键盘
     */
    override fun requestHideSoftKeyboard() {
        mTarget?.requestHideSoftKeyboard()
    }

    private class AirPanelLayout : AirPanel.Helper {
        private val mShowPanelIntention = AtomicBoolean(false)
        private val mLastFrame = Rect()
        private var mSubPanel: AirPanel.Panel
        private var mRootView: View? = null
        private var mPanelListener: AirPanel.PanelListener? = null
        private var mOnStateChangedListener: AirPanel.OnStateChangedListener? = null
        private var mDisplayHeight = 0
        private var mIsOpenPanel = false
        private var mIsOpenSoftKeyboard = false

        constructor(subPanel: AirPanel.Panel) {
            mSubPanel = subPanel
        }

        override fun setup(activity: Activity) {
            mRootView = activity.window.decorView
            val display = activity.windowManager.defaultDisplay
            val point = Point()
            display.getSize(point)
            mDisplayHeight = point.y
        }

        override fun setup(panelListener: AirPanel.PanelListener) {
            mPanelListener = panelListener
        }

        override fun openPanel() {
            if (isOpenSoftKeyboard()) {
                mShowPanelIntention.set(true)
                mPanelListener?.requestHideSoftKeyboard()
            } else {
                mSubPanel.openPanel()
                notifyStateChanged()
            }
        }

        override fun closePanel() {
            mSubPanel.closePanel()
            notifyStateChanged()
        }

        override fun isOpen(): Boolean {
            return mSubPanel.isOpen()
        }

        override fun calculateHeightMeasureSpec(heightMeasureSpec: Int): Int {
            updateFrameSize()
            return heightMeasureSpec
        }

        private fun updateFrameSize() {
            val frame = Rect() // 创建一个新区域
            mRootView?.getWindowVisibleDisplayFrame(frame) // 获取此时的rootView的区域大小
            var bottomChangeSize = 0 // 设置底部的变化大小
            if (mLastFrame.bottom > 0) {
                bottomChangeSize = frame.bottom - mLastFrame.bottom
            }
            mLastFrame.set(frame)
            AirPanelUtils.log("AirPanelHelper ${this.javaClass} setup frame = %s", frame)
            checkSoftKeyboardAction(bottomChangeSize)
        }

        private fun checkSoftKeyboardAction(bottomChangeSize: Int) {
            if (bottomChangeSize > 0 && !isOpenSoftKeyboard()) {
                mSubPanel.adjustPanelHeight(bottomChangeSize)
                if (mShowPanelIntention.getAndSet(false)) openPanel() else notifyStateChanged()
            } else if (bottomChangeSize < 0) {
                closePanel()
            }
        }

        override fun adjustPanelHeight(height: Int) {

        }

        override fun setOnStateChangedListener(listener: AirPanel.OnStateChangedListener) {
            mOnStateChangedListener = listener
        }

        private fun isOpenSoftKeyboard(): Boolean {
            return mLastFrame.bottom != 0 && mLastFrame.bottom < mDisplayHeight
        }

        override fun requestHideSoftKeyboard() {
            mPanelListener?.requestHideSoftKeyboard()
        }

        private fun notifyStateChanged() {
            val listener = mOnStateChangedListener ?: return
            val isOpenPanel = mSubPanel.isOpen()
            if (isOpenPanel != mIsOpenPanel) {
                mIsOpenPanel = isOpenPanel
                listener.onPanelStateChanged(isOpenPanel)
            }
            val isOpenSoftKeyboard = isOpenSoftKeyboard()
            if (isOpenSoftKeyboard != mIsOpenSoftKeyboard) {
                mIsOpenSoftKeyboard = isOpenSoftKeyboard
                listener.onSoftKeyboardStateChanged(isOpenSoftKeyboard)
            }
        }

    }

    private class AirPanelView : AirPanel.Helper {

        private var mView: View
        private var mPanelHeight = 0
        private var mAttribute: AirAttribute

        constructor(
            view: View,
            attribute: AirAttribute
        ) {
            mView = view
            mAttribute = attribute
            mPanelHeight = AirPanelUtils.getDefaultPanelHeight(
                view.context,
                attribute
            )
        }

        override fun openPanel() {
            Log.e("openPanel", "2 ")
            mView.visibility = View.VISIBLE
        }

        override fun closePanel() {
            mView.visibility = View.GONE
        }

        override fun isOpen(): Boolean {
            return mView.visibility != View.GONE
        }

        override fun calculateHeightMeasureSpec(heightMeasureSpec: Int): Int {
            val specMode = View.MeasureSpec.getMode(heightMeasureSpec)
            val specSize = View.MeasureSpec.getSize(heightMeasureSpec)

            var tempHeightMeasureSpec = heightMeasureSpec

            if (mPanelHeight > 0) {
                val newSpecMode = View.MeasureSpec.EXACTLY
                val newSpecSize = mPanelHeight
                tempHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(newSpecSize, newSpecMode)
                AirPanelUtils.log(
                    "calculateHeightMeasureSpec:oldMode:%s, oldSize:%s newMode:%s, newSize:%s",
                    specMode, specSize, newSpecMode, newSpecSize
                )
            } else {
                AirPanelUtils.log(
                    "calculateHeightMeasureSpec:oldMode:%s, size:%s",
                    specMode, specSize
                )
            }
            return tempHeightMeasureSpec
        }


        override fun adjustPanelHeight(requestHeight: Int) {
            val max = mAttribute.panelMaxHeight
            val min = mAttribute.panelMinHeight
            var height = requestHeight.coerceAtMost(max)
            height = height.coerceAtLeast(min)

            if (height != mPanelHeight) {
                mPanelHeight = height
                AirPanelUtils.updateLocalPanelHeight(mView.context, height)
            }
            AirPanelUtils.log(
                "adjustPanelHeight:in:%s, max:%s, min:%s, cur:%s",
                requestHeight,
                max,
                min,
                mPanelHeight
            )
        }


        override fun setup(activity: Activity) {
        }

        override fun setup(panelListener: AirPanel.PanelListener) {
        }


        override fun setOnStateChangedListener(listener: AirPanel.OnStateChangedListener) {
        }

        override fun requestHideSoftKeyboard() {
            // None do
        }

    }
}